package com.icode50.spring.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.camunda.bpm.engine.RuntimeService;
import org.camunda.bpm.engine.TaskService;
import org.camunda.bpm.engine.runtime.ProcessInstance;
import org.camunda.bpm.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.icode50.spring.model.ProjectParticipateRequestRecord;
import com.icode50.spring.model.ProjectProcessConstant;
import com.icode50.spring.model.UploadExtraInfoRecord;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api
@RestController
@RequestMapping("/test")
public class TestController {

	private final Logger LOGGER = LoggerFactory.getLogger(TestController.class);
	private final TaskService taskService;
	private final RuntimeService runtimeService;

	public TestController(TaskService taskService, RuntimeService runtimeService) {
		this.taskService = taskService;
		this.runtimeService = runtimeService;
	}

	@ApiOperation(value = "接口1：启动报名流程")
	@PostMapping(value = "/startProject")
	public boolean ParticipatingProject(Long projectId, Long userId) {
		Long savedRecordId = 3L;

		Map<String, Object> variables = new HashMap<String, Object>();
		variables.put(ProjectProcessConstant.VAR_NAME_SCHOOL, "华中科技大学");
		variables.put(ProjectProcessConstant.VAR_NAME_STUDENT, String.valueOf(userId));
		variables.put(ProjectProcessConstant.FORM_RECORD_ID, savedRecordId);

		ProcessInstance instance = runtimeService.startProcessInstanceByKey(ProjectProcessConstant.PROCESS_ID, variables);
		if (instance == null) {
			LOGGER.info("创建流程实例失败");
			return false;
		} else {
			LOGGER.info("创建流程实例成功");
			return true;
		}
	}

	@ApiOperation(value = "接口2：获取需要审批的项目申请Task列表")
	@PostMapping(value = "/approve/list")
	@ResponseBody
	public List<ProjectParticipateRequestRecord> getAllProjectParticipateRequest(String schoolName, Integer reviewLevel) {
		LOGGER.info("学校名称为:" + schoolName + ", 审核级别：" + reviewLevel + "级审核");
		// get the taskList
		List<Task> tasks;
		if (reviewLevel.equals(1)) {
			//一级审批
			tasks = taskService.createTaskQuery().taskName(ProjectProcessConstant.TASK_NAME_FIRST_LEVEL_REVIEW)
					.taskCandidateGroup(schoolName).list();
		} else {
			//二级审批
			tasks = taskService.createTaskQuery().taskName(ProjectProcessConstant.TASK_NAME_SECOND_LEVEL_REVIEW)
					.taskCandidateGroup(schoolName).list();
		}
		List<ProjectParticipateRequestRecord> records = new ArrayList<ProjectParticipateRequestRecord>(tasks.size());

		LOGGER.info("获取Record数量:" + records.size());
		tasks.forEach(task -> {
			ProjectParticipateRequestRecord record = new ProjectParticipateRequestRecord();
			String taskId = task.getId();
			Map<String, Object> variables = taskService.getVariables(taskId);

			Long studentId = Long.valueOf((String) variables.get(ProjectProcessConstant.VAR_NAME_STUDENT));
			Long recordId = (Long) variables.get(ProjectProcessConstant.FORM_RECORD_ID);
			record.setStudentId(studentId);
			record.setProjectParticipateId(recordId);
			record.setTaskId(taskId);

			records.add(record);
		});

		return records;
	}

	/*
	 * 审批一、审批二
	 */
	@ApiOperation(value = "接口3：执行项目申请审批(一级或二级)")
	@PostMapping(value = "/approveProject")
	public boolean approveProjectParticipateRequest(String taskId, boolean needExtraInfo, boolean passed,
			String schoolName) {
		Task task = taskService.createTaskQuery().taskCandidateGroup(schoolName).taskId(taskId).singleResult();
		if (task == null) {
			LOGGER.error("任务没有找到, TaskId=" + taskId);
			return false;
		} else {
			// business logic here
			// Into next step
			LOGGER.info("任务执行成功, TaskId={}", taskId);
			Map<String, Object> variables = new HashMap<>();
			variables.put(ProjectProcessConstant.FORM_EXTRA_INFO_1, needExtraInfo);
			variables.put(ProjectProcessConstant.FORM_APPROVED_1, passed);
			taskService.complete(task.getId(), variables);
			return true;
		}
	}

	@ApiOperation(value = "接口4：获取需要上传材料Task列表")
	@PostMapping(value = "/extraInfo/list")
	public List<UploadExtraInfoRecord> getUploadExtraTask(Long userId) {
		List<Task> uploadExtraInfoTask = taskService.createTaskQuery().taskAssignee(String.valueOf(userId))
				.taskName(ProjectProcessConstant.TASK_NAME_UPLOAD_EXTRA_INFO).list();

		List<UploadExtraInfoRecord> records = new ArrayList<>(uploadExtraInfoTask.size());
		uploadExtraInfoTask.forEach(task -> {
			UploadExtraInfoRecord record = new UploadExtraInfoRecord();
			record.setTaskId(task.getId());

			// the upload url of extra info is up to the variable
			record.setTheUploadUrlOfExtraInfo("www.icode50.com");

			records.add(record);
		});

		return records;
	}

	@ApiOperation(value = "接口5：执行上传资料方法")
	@PostMapping(value = "/extraInfo/upload")
	public boolean uploadExtraInfo(Long projectId, Long userId, String extraInfo, String taskId) {
		// must verify the task of the taskId pointing is belong the current user.
		Task task = taskService.createTaskQuery().taskAssignee(String.valueOf(userId))
				.taskName(ProjectProcessConstant.TASK_NAME_UPLOAD_EXTRA_INFO).taskId(taskId).singleResult();
		if (task == null) {
			LOGGER.error("任务未找到.");
			LOGGER.error("Assignee={}, TaskName={}, TaskId={}.", userId, ProjectProcessConstant.TASK_NAME_UPLOAD_EXTRA_INFO, taskId);
			return false;
		} else {
			// upload extra info to db.
			// business logic here
			// into next step
			LOGGER.info("完成上传资料方法，TaskId=" + task.getId());
			taskService.complete(task.getId());
			return true;
		}
	}
}
